<template>
	<div id="term" style="background-color: #1e1e1e; height: 100%; text-align: left;"></div>
</template>

<script>
	import {
		Terminal
	} from "xterm";
	import {
		FitAddon
	} from "xterm-addon-fit";
	import {
		Unicode11Addon
	} from "xterm-addon-unicode11";
	import "xterm/css/xterm.css"; // 这个css样式必须要引入，不然生成的terminal终端会有问题

	export default {
		data() {
			return {
				// 定义一些初始化变量
				term: "",
				ws: "",
				unicode11Addon: new Unicode11Addon(),
				fitAddon: new FitAddon(),
				prefix: "", //前缀
				command: "",
			}
		},

		mounted() {
			// 初始化终端
			this.initTerminal()
			this.websocket()
		},
		
		beforeDestroy() {
			this.ws.close()
			this.term.dispose()
		},

		methods: {
			// 初始化term终端
			initTerminal() {
				// 实例化term以及依赖包
				this.term = new Terminal({
					allowProposedApi: true,
					rendererType: "canvas", //渲染类型
					rows: 24, //行数
					cols: 185,
					fontSize: 14,
					fontFamily: 'Consolas, "Courier New", monospace',
					convertEol: true, // 启用时，光标将设置为下一行的开头
					scrollback: 100, // 终端中的回滚量
					disableStdin: false, //是否应禁用输入。
					cursorStyle: 'underline', //光标样式
					cursorBlink: true, //光标闪烁
					theme: {
						foreground: '#ffffff', //字体
						// background: '#060101', //背景色
						background: '#1C1C1C', //背景色
						cursor: 'help', //设置光标
					}
				})
				this.term.loadAddon(this.fitAddon);
				this.term.loadAddon(this.unicode11Addon);
				this.term.unicode.activeVersion = "11";
				this.term.onResize((size) => {
					console.log(size.rows, size.cols)
				});
				// 将term挂载到dom元素上
				const terminalContainer = document.getElementById("term");
				this.term.open(terminalContainer);
				this.fitAddon.fit()
				this.term.focus()

				// this.term.write("hello, welcome to terminal!\r\n")
				// this.term.writeln("\x1b[1;1;32mwellcom to web terminal!\x1b[0m");
				// this.term.writeln("Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ");
				// this.term.writeln("Hello world!!!");

				// this.term.writeln(this.prefix + "123123")
				// this.userWrite()
			},
			
			writeOfColor(txt, fontCss = "", bgColor = ""){
				// 在Linux脚本中以 \x1B[ 开始，中间前部分是样式+内容，以 \x1B[0m 结尾
				// 示例 \x1B[1;3;31m 内容 \x1B[0m  
				// fontCss
				// 0;-4;字体样式（0;正常 1;加粗 2;变细 3;斜体 4;下划线）
				// bgColor
				// 30m-37m字体颜色（30m:黑色 31m:红色 32m:绿色 33m:棕色字 34m:蓝色 35m:洋红色/紫色 36m:蓝绿色/浅蓝色 37m:白色）
				// 40m-47m背景颜色（40m:黑色 41m:红色 42m:绿色 43m:棕色字 44m:蓝色 45m:洋红色/紫色 46m:蓝绿色/浅蓝色 47m:白色）
				this.term.write(`${txt}`)
			},
			
			// 监听输入
			userWrite(){
				// this.term.write(this.prefix);
				
				this.term.onData(e => {
					switch (e) {
						case '\u0003': // Ctrl+C
							this.term.write('\r\n');
							this.term.write(this.prefix + '^C ');
						break;
						
						case '\r': // Enter
							this.ws.send(this.command)
							// this.ws.send('\n') 
							// this.command = ''
							this.term.write('\r\n');
							//this.term.write(this.prefix)
						break;
						
						case '\u007F': // Backspace (DEL)
							// Do not delete the prompt
							if (this.term._core.buffer.x > 2) {
								this.term.write('\b \b');
								if (this.command.length > 0) {
									this.command = this.command.substr(0, this.command.length - 1);
								}
							}
						break;
						
						default: // Print all other characters for demo
							if (e >= String.fromCharCode(0x20) && e <= String.fromCharCode(0x7E) || e >= '\u00a0') {
								this.term.write(e)
								this.command += e;
								console.log('用户输入command',this.command)
							}
					}
				});
			},
			
			websocket() {
				this.ws = new WebSocket('ws://api.xman.com:9050/ws/ssh/1/')
				this.$nextTick(()=>{
					this.userWrite()
				})
				
				this.ws.onopen = (event) => {
					console.log('已建立连接：',event)
					// 输入换行符可让终端显示当前用户的工作路径
					// this.ws.send('\n') 
				};
				
				this.ws.onmessage = (event) => {
					console.log('接收信息：',event)
					console.log('收到的消息内容: ', event.data.replace(event.data.split('\r\n', 1)[0] + "\r\n", ''));
					
					/*
					//将字符串转换成 Blob对象
					const blob = new Blob([event.data], {
						type: 'text/plain'
					});
					//将Blob 对象转换成字符串
					const reader = new FileReader();
					reader.readAsText(blob, 'utf-8');
					reader.onload = (e) => {
						// 可以根据返回值判断使用何种颜色或者字体，不过返回值自带了一些字体颜色
						this.writeOfColor(reader.result)
					}
					*/
					
					if (!this.command) {
						//所要执行的操作
						this.term.write(event.data);
					} else {
						console.log(event.data.split('\r\n'))
						this.command = ''
						let res = event.data.replace(event.data.split('\r\n', 1)[0] + "\r\n", '');
						this.term.write(res)
					}
				};
				
				this.ws.onerror = (event) => {
					console.log('错误信息：', event)
					if (wsTime) {
						window.clearTimeout(wsTime)
						wsTime = null
					}
					wsTime = window.setTimeout(() => {
						this.websocket()
					}, 3000)
				};
				
				this.ws.onclose = (event) => {
					console.log('已关闭连接：', event)
					// if (wsTime) {
					//    window.clearTimeout(wsTime)
					//    wsTime = null
					// }
					// wsTime = window.setTimeout(() => {
					//    this.websocket()
					// }, 3000)
				};

			}

		}
	}
</script>